﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace CSMF.ValidateCode.lib
{
    public class CodeValue
    {
        public DateTime CreateTime { get; set; }
        public string Code { get; set; }
    }

    public static class Utility
    {
        static Hashtable cache = null;
        public static Hashtable GetHashtable()
        {
            if (cache == null)
                cache = new Hashtable();

            return cache;
        }

        /// <summary>
        /// 由随机字符串，随即颜色背景，和随机线条产生的Image
        /// 返回 MemoryStream
        /// </summary>
        /// <returns>MemoryStream</returns>
        public static void GetImgWithValidateCode(string validStr, string imgName, int charNum)
        {
            int width = 100;
            int height = 28;
            int fontSize = 20;

            //声明一个位图对象
            Bitmap bitMap = null;
            //声明一个绘图画面
            Graphics gph = null;
            Random random = new Random();

            //由给定的需要生成字符串中字符个数 CharNum， 图片宽度 Width 和高度 Height 确定字号 FontSize，
            //确保不因字号过大而不能全部显示在图片上
            int fontWidth = (int)Math.Round(width / (charNum + 2) / 1.3);
            int fontHeight = (int)Math.Round(height / 1.5);
            //字号取二者中小者，以确保所有字符能够显示，并且字符的下半部分也能显示
            //fontSize = fontWidth <= fontHeight ? fontWidth : fontHeight;

            //创建位图对象
            bitMap = new Bitmap(width + fontSize, height);

            //根据上面创建的位图对象创建绘图图面
            gph = Graphics.FromImage(bitMap);

            //设定验证码图片背景色
            gph.Clear(GetControllableColor(200));

            //定义一个含10种字体的数组
            String[] fontFamily ={ "Arial", "Verdana", "Comic Sans MS", "Impact", "Haettenschweiler", 
                                        "Lucida Sans Unicode", "Garamond", "Courier New", "Book Antiqua", "Arial Narrow" };
            //              SolidBrush sb = new SolidBrush(GetControllableColor(0));

            PointF Cpoint1 = new PointF(5, 5);
            Random rnd1 = new Random();
            int x1 = 0, y1 = 0;
            //通过循环,绘制每个字符,
            for (int i = 0; i < validStr.Length; i++)
            {
                //随机字符位置   
                x1 = rnd1.Next(8) + fontSize * i;
                y1 = rnd1.Next(bitMap.Height / 4);
                Cpoint1 = new PointF(x1, y1);

                //随机字符颜色,应根据背景作适当调整以免显示模糊不清
                SolidBrush sb = new SolidBrush(Color.FromArgb(rnd1.Next(100), rnd1.Next(100), rnd1.Next(100)));


                //Font textFont = new Font(fontFamily[random.Next(10)], fontSize, FontStyle.Bold);//字体随机,字号大小30,加粗 
                Font textFont = new Font("Arial", fontSize, FontStyle.Bold);//字体随机,字号大小30,加粗 

                //随机倾斜字符  
                gph.TranslateTransform(10, 0);
                Matrix transform = gph.Transform;
                transform.Shear(Convert.ToSingle(rnd1.NextDouble() - 0.5), 0.001f);
                gph.Transform = transform;
                //每次循环绘制一个字符,设置字体格式,画笔颜色,字符相对画布的X坐标,字符相对画布的Y坐标
                //int space = (int)Math.Round((double)((width - fontSize * (CharNum + 2)) / CharNum));
                //纵坐标
                int y = (int)Math.Round((double)((height - fontSize) / 3));
                //                  gph.DrawString(validStr.Substring(i, 1), textFont, sb, fontSize + i * (fontSize + space), y);
                gph.DrawString(validStr.Substring(i, 1), textFont, sb, Cpoint1);
                gph.ResetTransform();
            }

            //画图片的边框线
            gph.DrawRectangle(new Pen(Color.Black, 2), 0, 0, bitMap.Width - 1, bitMap.Height - 1);

            try
            {
                bitMap.Save(imgName, ImageFormat.Jpeg);
            }
            catch (Exception ex)
            {
                // TODO; a
                //System.Windows.Forms.MessageBox.Show(ex.Message);
            }

            bitMap.Dispose();
        }

        /// <summary>
        /// 产生一种 R,G,B 均大于 colorBase 随机颜色，以确保颜色不会过深
        /// </summary>
        /// <param name="colorBase">The color base.</param>
        /// <returns>背景色</returns>
        static Color GetControllableColor(int colorBase)
        {
            Color color = Color.Black;
            if (colorBase > 200)
            {
                //System.Windows.Forms.MessageBox.Show("可控制颜色参数大于200，颜色默认位黑色");
            }
            Random random = new Random();
            //确保 R,G,B 均大于 colorBase，这样才能保证背景色较浅
            color = Color.FromArgb(random.Next(56) + colorBase, random.Next(56) + colorBase, random.Next(56) + colorBase);
            return color;
        }

        /// <summary>
        /// 产生指定个数的随机字符串，默认字符个数为5
        /// </summary>
        public static string GetValidateCode(int charNum)
        {
            string validStr = string.Empty;
            Random rd = new Random(); //创建随机数对象            

            //产生由 charNum 个字母或数字组成的一个字符串
            string str = "ABCDEFGHJKLMNPQRSTUVWYZ23456789";//共31个字符，除 l,o,x,I,O,X,1,0 的所有数字和大写字母

            for (int i = 0; i < charNum; i++)
            {
                validStr = validStr + str[rd.Next(30)];//返回0到54
            }

            return validStr;
        }
    }
}